package storage

import (
	"context"
	"errors"
	"io"
	"log"
	"os"
	"path/filepath"
)

type LocalFileStorage struct {
	BasePath string
}

func NewLocalFileStorage(ctx context.Context, basePath string) *LocalFileStorage {
	// 如果用户目录不存在则创建
	if !IsExist(basePath) {
		MkDir(basePath)
	}

	return &LocalFileStorage{
		BasePath: basePath,
	}
}

func MkDir(path string) interface{} {
	return os.MkdirAll(path, os.ModePerm)
}

func IsExist(path string) bool {
	_, err := os.Stat(path)
	return !os.IsNotExist(err)
}

func (l *LocalFileStorage) getFullPath(objectKey string) string {
	return filepath.Join(l.BasePath, objectKey)
}

func (l *LocalFileStorage) Upload(ctx context.Context, objectKey string, reader io.Reader, size int64, contentType string) error {
	fullPath := l.getFullPath(objectKey)

	// 创建目录（递归创建）
	if err := os.MkdirAll(filepath.Dir(fullPath), os.ModePerm); err != nil {
		return err
	}

	// 创建文件
	dst, err := os.Create(fullPath)
	if err != nil {
		return err
	}
	defer func(dst *os.File) {
		err := dst.Close()
		if err != nil {
			log.Fatalf("Error closing file: %v, error: %v", objectKey, err)
		}
	}(dst)

	// 写入文件内容
	_, err = io.Copy(dst, reader)
	return err
}

func (l *LocalFileStorage) Download(ctx context.Context, objectKey string) (io.ReadCloser, error) {
	fullPath := l.getFullPath(objectKey)

	file, err := os.Open(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return nil, errors.New("file not found")
		}
		return nil, err
	}
	return file, nil
}

func (l *LocalFileStorage) Delete(ctx context.Context, objectKey string) error {
	fullPath := l.getFullPath(objectKey)

	// 如果不存在直接返回 nil
	if _, err := os.Stat(fullPath); os.IsNotExist(err) {
		return nil
	}

	return os.Remove(fullPath)
}

func (l *LocalFileStorage) Size(ctx context.Context, objectKey string) (int64, error) {
	fullPath := l.getFullPath(objectKey)

	fileInfo, err := os.Stat(fullPath)
	if err != nil {
		if os.IsNotExist(err) {
			return 0, errors.New("file not found")
		}
		return 0, err
	}

	return fileInfo.Size(), nil
}
